import { Context, Next } from 'koa';
import { JwtUtil } from '@/utils/jwt';
import { AppError } from './error';

/**
 * JWT 认证中间件
 */
export const authMiddleware = async (ctx: Context, next: Next): Promise<void> => {
  try {
    const authorization = ctx.headers.authorization as string;
    const token = JwtUtil.extractTokenFromHeader(authorization);

    if (!token) {
      throw new AppError('未提供访问令牌', 401);
    }

    // 验证 token
    const payload = JwtUtil.verifyToken(token);
    
    // 将用户信息添加到上下文中
    ctx.state.user = payload;

    await next();
  } catch (error) {
    if (error instanceof AppError) {
      throw error;
    }
    throw new AppError('令牌验证失败', 401);
  }
};

/**
 * 可选认证中间件（token 存在时验证，不存在时跳过）
 */
export const optionalAuthMiddleware = async (ctx: Context, next: Next): Promise<void> => {
  try {
    const authorization = ctx.headers.authorization as string;
    const token = JwtUtil.extractTokenFromHeader(authorization);

    if (token) {
      try {
        const payload = JwtUtil.verifyToken(token);
        ctx.state.user = payload;
      } catch {
        // 忽略验证失败，继续执行
      }
    }

    await next();
  } catch (error) {
    await next();
  }
};

/**
 * 角色权限中间件
 */
export const roleMiddleware = (allowedRoles: string[]) => {
  return async (ctx: Context, next: Next): Promise<void> => {
    const user = ctx.state.user;

    if (!user) {
      throw new AppError('未认证用户', 401);
    }

    if (!user.role || !allowedRoles.includes(user.role)) {
      throw new AppError('权限不足', 403);
    }

    await next();
  };
};

/**
 * 管理员权限中间件
 */
export const adminMiddleware = roleMiddleware(['admin']);

/**
 * 用户或管理员权限中间件
 */
export const userOrAdminMiddleware = roleMiddleware(['user', 'admin']);

export default authMiddleware;